#include "FileSys.h"

#include <QCoreApplication>
#include <QStandardPaths>
#include <QDir>
#include <QFileInfo>

FileSys::FileSys()
{
    Q_ASSERT_X(qApp, "FileSys Construction!", "QApplication should be there!");
    if(qApp)
        m_exeDir = qApp->applicationDirPath();

    m_appName = qApp->applicationName();
    m_userId = "Taurus";
    //TODO: get user name
}

FileSys* FileSys::instance()
{
    static FileSys s_instance;
    return &s_instance;
}

QString FileSys::runRootDir( ) const
{
    return m_exeDir;
}

QString FileSys::appCfgDir() const
{
    return m_exeDir + "/config";
}

QString FileSys::logDir() const
{
    //TODO: should put logs dir in user's data dir
    return m_exeDir + "/logs";
}

QString FileSys::userCfgDir() const
{
    return m_exeDir + "/config/User/" + m_userId;
//#if _DEBUG
//    return m_exeDir + "/user/config";
//#endif
//    static QString s_userCfgDir = QStandardPaths::writableLocation(QStandardPaths::StandardLocation::AppDataLocation) \
//                                    .append("/").append(m_userId).append("/config");

    //return s_userCfgDir;
}

QString FileSys::tmpDir() const
{
    return m_exeDir + "/temp";
//#if _DEBUG
//    return m_exeDir + "/temp";
//#endif
//    static QString s_tmpDir = QStandardPaths::writableLocation(QStandardPaths::StandardLocation::TempLocation);
    //return s_tmpDir;
}

bool FileSys::createFile(const QString& fullFileName, QIODevice::OpenModeFlag flag, QFile*& file) const
{
    QFileInfo fi(fullFileName);
    fi.absoluteDir().mkpath(fi.absolutePath());

    file = new QFile(fullFileName);
    if (file->open(flag))
        return true;

    delete file;
    file = nullptr;
    return false;
}

bool FileSys::closeFile(QFile* file) const
{
    if (file)
    {
        file->close();
        delete file;
        file = nullptr;

        return true;
    }

    return false;
}

int64_t FileSys::getFileSize(QFile* file) const
{
    if (!file)
    {
        return 0;
    }
    return file->size();
}

int64_t FileSys::readFile(QFile* file, char *data, int64_t maxlen)
{
    if (!file)
    {
        return 0;
    }
    return file->read(data, maxlen);
}

int FileSys::copyFile(const char* src, const char* des)
{
    int nRet = 0;
    FILE* pSrc = NULL, * pDes = NULL;
    pSrc = fopen(src, "r");
    pDes = fopen(des, "w+");

    if (pSrc && pDes)
    {
        int nLen = 0;
        char szBuf[1024] = { 0 };
        while ((nLen = fread(szBuf, 1, sizeof szBuf, pSrc)) > 0)
        {
            fwrite(szBuf, 1, nLen, pDes);
        }
    }
    else
        nRet = -1;

    if (pSrc)
        fclose(pSrc), pSrc = NULL;

    if (pDes)
        fclose(pDes), pDes = NULL;

    return nRet;
}

bool FileSys::removeFile(const QString& fullFileName) const
{
    if (fullFileName.isEmpty())
        return true;
    return QFile::remove(fullFileName);
}

bool FileSys::isFileExist(const QString& fullFileName) const
{
    QFile file(fullFileName);
    return file.exists();
}

bool FileSys::isFileWritable(const QString& fullFileName) const
{
    QFile file(fullFileName);
    QFileInfo fileInfo(file);

    if (!file.open(QIODevice::ReadWrite))
    {
        return false;
    }

    return fileInfo.isWritable();
}

bool FileSys::makePathExist(const QString& path) const
{
    QDir dir;
    return dir.mkpath(path);
}

void FileSys::makeSlashPath(qb::base::BaseString& path)
{
    if(path.size()>0)
    {
        if(path.at(path.size()-1)!='\\' && path.at(path.size()-1)!='/')
            path.push_back('\\');
    }
}

qb::base::BaseString FileSys::getSlashPath(const char* path)
{
    qb::base::BaseString slashp = path;
    makeSlashPath(slashp);
    return slashp;
}
